package com.itcam.cm.common.log.aspect;


import com.alibaba.fastjson.JSON;
import com.itcam.cm.common.log.annotation.Log;
import com.itcam.cm.common.log.enums.OperatorType;
import com.itcam.cm.common.log.service.SysOperLogService;
import com.itcam.cm.model.entity.system.SysOperLog;
import com.itcam.cm.model.entity.system.SysUser;
import com.itcam.cm.model.entity.system.SysUserThreadLocalAuthContextUtil;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
public class LogAspect {

    @Autowired
    SysOperLogService sysOperLogService;

    @SneakyThrows
    @Around("@annotation(sysLog)")
    public Object a(ProceedingJoinPoint joinPoint , Log sysLog){

        // 日志
        SysOperLog sysOperLog = new SysOperLog();

        // 方法的执行前
        System.out.println("执行被代理方法执行之前");// 获得各种参数和请求信息
        beforeLog(sysOperLog,sysLog,joinPoint);

        // 执行被代理方法
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        }catch (Exception e){
            afterLog(sysOperLog,sysLog,proceed,1,e.getMessage());
            // 保存日志
            sysOperLogService.saveLog(sysOperLog);
            throw new Exception(e);
            // return null;
        }

        // 方法执行后
        System.out.println("执行被代理方法执行之后");// 获得执行结果
        afterLog(sysOperLog,sysLog,proceed,0,null);

        // 保存日志
        sysOperLogService.saveLog(sysOperLog);

        // 返回执行结果
        return proceed;
    }

    private void afterLog(SysOperLog sysOperLog, Log sysLog, Object proceed,Integer status,String message) {
        sysOperLog.setStatus(status);
        if(status==0){
            if(proceed!=null){
                sysOperLog.setJsonResult(JSON.toJSONString(proceed));
            }
        }else {
            sysOperLog.setErrorMsg(message);
        }
    }

    private void beforeLog(SysOperLog sysOperLog, Log sysLog, ProceedingJoinPoint joinPoint) {

        // 注解信息
        int i = sysLog.businessType();// 业务类型
        String title = sysLog.title();// 模块名
        OperatorType operatorType = sysLog.operatorType();
        sysOperLog.setBusinessType(i);
        sysOperLog.setTitle(title);
        sysOperLog.setOperatorType(operatorType.name());

        // http信息
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String requestURI = request.getRequestURI();
        String method = request.getMethod();
        String ip = request.getRemoteAddr();
        StringBuffer requestURL = request.getRequestURL();
        String queryString = request.getQueryString();
        sysOperLog.setOperUrl(requestURL.toString());
        sysOperLog.setOperParam(queryString);
        sysOperLog.setRequestMethod(method);
        sysOperLog.setOperIp(ip);

        // 方法本身
        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
        String name = methodSignature.getName();
        sysOperLog.setMethod(name);
        SysUser sysUser = SysUserThreadLocalAuthContextUtil.get();
        sysOperLog.setOperName(sysUser.getUsername());


    }

}
